/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2014.10.23                                          *
 * Description:      build unstructured mesh from file                   *
 *                                                                       *
 *************************************************************************/

//declaration header
#include "COMMON/mesh/MeshReader.h"

//COMMON headers
#include "COMMON/info/InfoManager.h"
#include "COMMON/info/CommonInfo.h"
//#include "COMMON/mesh/GambitIO.h"
//#include "COMMON/mesh/FluentIO.h"
#include "COMMON/tbox/InputDatabase.h"
#include "COMMON/tbox/LogMessage.h"
#include "COMMON/tbox/Utilities.h"

#include <fstream>


namespace FreeMAPs
{

MeshReader::MeshReader():
    Parent             ("unstructured_mesh_info", "mesh_reader", false),
    d_mesh_package     (MeshPackage::LIBMESH),
    d_mesh_file_format (MeshFileFormat::GAMBIT)
{}



MeshReader::~MeshReader()
{
    d_mesh_file_location.clear();
}



bool
MeshReader::check_all_info_db (
        const InputDatabase* db)
{
    //mesh_file_format
    if( !db->key_exists("mesh_file_format") )
    {
        FREEMAPS_ERROR("in \"mesh_reader\", can not find  \"mesh_file_format\" \n");
        return false;
    }
    if( !db->is_string("mesh_file_format") )
    {
        FREEMAPS_ERROR("in \"mesh_reader\", \"mesh_file_format\" should be string \n");
        return false;
    }

    //mesh_file_location
    if( db->key_exists("mesh_file_location") )
    {
        if( !db->is_string("mesh_file_location") )
        {
            FREEMAPS_ERROR("in \"mesh_reader\", \"mesh_file_location\" should be string \n");
            return false;
        }

        //mesh file exist or not
        std::string file_name = db->get_string("mesh_file_location");
        std::ifstream fin(file_name);
        if( !fin )
        {
            FREEMAPS_ERROR("in \"mesh_reader\", in \"mesh_file_location\", can not find the mesh file! \n");
            fin.close();
            return false;
        }
        fin.close();
    }
    else
    {
        FREEMAPS_ERROR("in \"mesh_reader\", can not find  \"mesh_file_location\" \n");
        return false;
    }

    return true;
}



void
MeshReader::get_from_input (
    const InputDatabase* db)
{
    this->prepare_for_use (db);

    db->insert_allowable_key ("mesh_package");
    db->insert_allowable_key ("mesh_file_format");
    db->insert_allowable_key ("mesh_file_location");

    db->check_allowable_keys();

    /*
    * build mesh_package
    */
    {
        if( db->key_exists("mesh_package") && db->is_string("mesh_package"))
        {
            db->check_optional_key ("mesh_package", DataType::STRING, true, false);
            d_mesh_package = db->get_enum_with_default ("mesh_package", d_mesh_package);
        }
    }

    /*
     * build mesh_file_format
     */
    {
        if( db->key_exists("mesh_file_format") && db->is_string("mesh_file_format"))
        {
            db->check_optional_key ("mesh_file_format", DataType::STRING, true, false);
            d_mesh_file_format = db->get_enum_with_default ("mesh_file_format", d_mesh_file_format);
        }
    }

    /*
     * build mesh_file_location
     */
    {
        if( db->key_exists("mesh_file_location") && db->is_string("mesh_file_location"))
        {
            db->check_requisite_key ("mesh_file_location", DataType::STRING, false, false);
            d_mesh_file_location = db->get_string ("mesh_file_location");
        }
    }
}



std::ostream&
operator << (
    std::ostream& os,
    const MeshReader& rhs)
{
    os << "mesh_reader\n{\n";

    const int max_width = std::string ("mesh_file_location").size();

//    os << LogMessage::get_equal_width_string ("mesh_package",       ONE_TAB, max_width) << " = \"" << Utilities::enum_to_string (rhs.d_mesh_package) << "\"\n";
    os << LogMessage::get_equal_width_string ("mesh_file_format",   ONE_TAB, max_width) << " = \"" << Utilities::enum_to_string (rhs.d_mesh_file_format) << "\"\n";
    os << LogMessage::get_equal_width_string ("mesh_file_location", ONE_TAB, max_width) << " = \"" << rhs.d_mesh_file_location << "\"\n";

    os << "}";

    return os;
}

}
